﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Web;
using System.Net;
using Newtonsoft.Json;

namespace TableOCR
{
    public partial class FormApp : Form
    {

        private bool isTableMode = true;
        public class ResultInfo
        {
            public List<OcrInfo> result { get; set; }

            public int success { get; set; }
        }

        public class OcrInfo
        {
            public string content { get; set; }

            public List<string> frame { get; set; }
        }


        public FormApp()
        {
            InitializeComponent();
            AppInit();
        }

        private void AppInit()
        {
            this.FormClosing += FormApp_FormClosing;
            this.Activated += Form_Activated;
            this.Leave += FrmSale_Leave;

        }
        private void buttonConfim_ClickAsync(object sender, EventArgs e)
        {
            Snapshot();
        }

        private void Snapshot()
        {
            this.Visible = false;
            FormSnapShot formSnapShot = new FormSnapShot();
            this.webBrowserApp.DocumentText = null;
            if (formSnapShot.ShowDialog() == DialogResult.OK)
            {
                Bitmap bitmap = formSnapShot.Snapshot;
                ShowPic(bitmap);
                string fileName = SavePic(bitmap);
                string serverURL = null;
                ResultInfo resultInfo = null;
                try
                {
                    serverURL = GetServerURL(fileName);
                    if (serverURL != null)
                    {
                        resultInfo = GetJson(serverURL);
                    }

                }
                catch (WebException e)
                {
                    MessageBox.Show(e.Message);
                }
                if (resultInfo != null && resultInfo.result != null)
                {
                    string content = null;
                    if (this.isTableMode)
                    {
                        content = HtmlTable(resultInfo);
                    }
                    else
                    {
                        content = HtmlUl(resultInfo);
                    }
                    this.webBrowserApp.DocumentText = content;
                }

            }
        }

        private string HtmlTable(ResultInfo resultInfo)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine(@"<html>");
            sb.AppendLine(@"<head>");
            sb.AppendLine("<style>table,tr,td {border: 1px #000 solid;} \n table {text-align: center;border-collapse:collapse;border-spacing:0px;} \n td {width:50px;}</style>");
            sb.AppendLine(@"</head>");
            sb.AppendLine(@"<body>");
            sb.AppendLine(@"<table>");
            sb.AppendLine(@"<tbody>");
            foreach (var item in resultInfo.result)
            {
                sb.AppendLine(@"<tr>");
                string[] array = item.content.Trim('\n').Split('|', ' ');
                foreach (var s in array)
                {
                    if (!string.IsNullOrEmpty(s))
                    {
                        sb.AppendLine(@"<td>" + s + "</td>");
                    }
                }
                sb.AppendLine(@"</tr>");
            }
            sb.AppendLine(@"</tbody>");
            sb.AppendLine(@"</table>");
            sb.AppendLine(@"</body>");
            sb.AppendLine(@"</html>");
            return sb.ToString();
        }
        private string HtmlUl(ResultInfo resultInfo)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine(@"<html>");
            sb.AppendLine(@"<head>");
            sb.AppendLine("<style></style>");
            sb.AppendLine(@"</head>");
            sb.AppendLine(@"<body>");
            sb.AppendLine(@"<ul>");
            foreach (var item in resultInfo.result)
            {
                sb.AppendLine(@"<li>");
                sb.AppendLine(item.content);
                sb.AppendLine(@"</li>");
            }
            sb.AppendLine(@"</ul>");
            sb.AppendLine(@"</body>");
            sb.AppendLine(@"</html>");
            return sb.ToString();
        }

        private ResultInfo GetJson(string serverURL)
        {

            string url = "http://pic.sogou.com/pic/ocr/ocrOnline.jsp?query=" + serverURL;
            WebClient webClient = new WebClient()
            {
                Encoding = Encoding.UTF8
            };
            var result = webClient.DownloadString(url);
            ResultInfo resultInfo = JsonConvert.DeserializeObject<ResultInfo>(result);
            return resultInfo;


        }

        private string GetServerURL(string fileName)
        {

            string url = "http://pic.sogou.com/pic/upload_pic.jsp";
            var result = new WebClient().UploadFile(url, fileName);
            return Encoding.UTF8.GetString(result);


        }

        private static string SavePic(Bitmap bitmap)
        {
            string fileName = "./ocr.jpg";

            if (File.Exists(fileName))
            {
                File.Delete(fileName);
            }
            bitmap.Save(fileName);
            return fileName;
        }

        private void ShowPic(Bitmap bitmap)
        {
            this.pictureBoxLeft.Image = bitmap;
            this.Visible = true;
        }

        private void FormApp_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                this.Visible = false;
                e.Cancel = true;
            }
        }

        private void toolStripMenuItemOpen_Click(object sender, EventArgs e)
        {
            this.Visible = true;
        }

        private void toolStripMenuItemClose_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void notifyIconApp_DoubleClick(object sender, EventArgs e)
        {
            this.Visible = true;
        }

        private void Form_Activated(object sender, EventArgs e)
        {
            //注册热键Shift+S，Id号为100。HotKey.KeyModifiers.Shift也可以直接使用数字4来表示。
            //HotKey.RegisterHotKey(Handle, 100, HotKey.KeyModifiers.Shift, Keys.S);
            //注册热键Ctrl+B，Id号为101。HotKey.KeyModifiers.Ctrl也可以直接使用数字2来表示。
            HotKey.RegisterHotKey(Handle, 101, HotKey.KeyModifiers.Ctrl, Keys.B);
            //注册热键Alt+D，Id号为102。HotKey.KeyModifiers.Alt也可以直接使用数字1来表示。
            //HotKey.RegisterHotKey(Handle, 102, HotKey.KeyModifiers.Alt, Keys.D);
        }
        //在FormA的Leave事件中注销热键。
        private void FrmSale_Leave(object sender, EventArgs e)
        {
            //注销Id号为100的热键设定
            //HotKey.UnregisterHotKey(Handle, 100);
            //注销Id号为101的热键设定
            HotKey.UnregisterHotKey(Handle, 101);
            //注销Id号为102的热键设定
            //HotKey.UnregisterHotKey(Handle, 102);
        }


        /// 
        /// 监视Windows消息
        /// 重载WndProc方法，用于实现热键响应
        /// 
        /// 
        protected override void WndProc(ref Message m)
        {

            const int WM_HOTKEY = 0x0312;
            //按快捷键 
            switch (m.Msg)
            {
                case WM_HOTKEY:
                    switch (m.WParam.ToInt32())
                    {
                        //case 100:    //按下的是Shift+S
                        //             //此处填写快捷键响应代码 
                        //    break;
                        case 101:    //按下的是Ctrl+B
                            Snapshot();       //此处填写快捷键响应代码
                            break;
                            //case 102:    //按下的是Alt+D
                            //             此处填写快捷键响应代码
                            //    break;
                    }
                    break;
            }
            base.WndProc(ref m);
        }

        private void radioButtonTable_Click(object sender, EventArgs e)
        {
            this.isTableMode = true;
        }

        private void radioButtonList_Click(object sender, EventArgs e)
        {
            this.isTableMode = false;
        }
    }
}
